package com.yy.micro.magic.core.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yy.micro.magic.core.domain.MagicRequest;
import com.yy.micro.magic.core.filter.FilterChain;
import com.yy.micro.magic.core.strategy.RuleStrategy;
import org.springframework.util.StringUtils;

 /**
   * @author YY
   * @version 1.0.0
   * @update 2021/9/20 10:50 下午
   * @description: 运行时源数据当前数据节点的元数据，包含了，数据节点的地址（路径），值，及待执行的变换策略。
 */
public class RuntimeMetadata {

     /**
      * 源数据中数据节点的地址。
      */
    private RuleKey key;
     /**
      * 数据节点的值
      */
    private Object value;
     /**
      * 数据节点待执行的变换策略{@link RuleStrategy}
      */
    private String strategy;

    private RuleDescriptor rule;

    private MagicRequest request;

    private ResultCollector collector;

     /**
      * 源数据节点是否输出到结果集中
      */
    private boolean includeRuntime;

    public String getPlanCode() {
        return request.getPlanCode();
    }

    public String getKey() {
        return key.getKey();
    }

    public RuleKey getRuleKey(){
        return key;
    }
    public void setKey(final String key) {
        this.key = RuleKey.create(key);
    }

    public String getName() {
        RuleDescriptor rule = getRule();
        if(null != rule){
            return rule.getName();
        }
        return key.getName();
    }

    public Object getValue() {
        return value;
    }

    public RuntimeMetadata setValue(final Object value) {
        this.value = value;
        return this;
    }

    public String getStrategy() {
        if (null != rule){
            return rule.getStrategy();
        }
        return StringUtils.isEmpty(strategy)?"valueCopy":strategy;
    }

    public void setStrategy(final String strategy) {
        this.strategy = strategy;
    }

    public RuleDescriptor getRule() {
        return rule;
    }

    public RuntimeMetadata setRule(final RuleDescriptor rule) {
        this.rule = rule;
        return this;
    }

    public String getProcessor() {
        return request.getProcessor();
    }

    public MagicRequest getRequest() {
        return request;
    }

    public RuntimeMetadata setRequest(final MagicRequest request) {
        this.request = request;
        return this;
    }

    public boolean isIncludeRuntime() {
        return includeRuntime;
    }

    public RuntimeMetadata setIncludeRuntime(final boolean includeRuntime) {
        this.includeRuntime = includeRuntime;
        return this;
    }

    public Object getInputValue(){
        return  getInputValue(false);
    }
    public Object getInputValue(boolean defaultValue){
        String input = rule.getInput();
        if (!StringUtils.isEmpty(input)){
            return request.getRuntimeData().get(input);
        }else if (defaultValue){
            if (null == value){
                return rule.getValue();
            }
            return value;
        }
        return null;
    }

    public ResultCollector getCollector() {
        return collector;
    }

    public RuntimeMetadata setCollector(final ResultCollector collector) {
        this.collector = collector;
        return this;
    }

    public FilterChain getHeadChain(){
        return getRequest().getContext().getComponentManager().getHeadFilterChain(getPlanCode());
    }

    public RuntimeMetadata clone(){
        RuntimeMetadata r =new RuntimeMetadata();
        r.strategy = this.strategy;
        r.rule = this.rule;
        r.request = this.request;
        r.collector = this.collector;
        r.includeRuntime = r.includeRuntime;
        r.key = this.key;
        r.value = this.value;
        return r;
    }

    @JsonIgnore
    public RuntimeMetadata from(MagicRequest request){
        setRequest(request);
        return this;
    }

    public static RuntimeMetadata create(String key){
        RuntimeMetadata metadata = new RuntimeMetadata();
        metadata.setKey(key);
        return metadata;
    }
}
